package qdrant

import (
	"context"
	"sync"
	"time"
)

// ThreadSafeClient 提供线程安全的Qdrant客户端封装
type ThreadSafeClient struct {
	client QdrantClient
	mutex  sync.RWMutex

	// 连接池相关
	maxConnections int
	activeConns    int
	connSemaphore  chan struct{}

	// 重试配置
	maxRetries   int
	retryBackoff time.Duration
}

// NewThreadSafeClient 创建线程安全的客户端
func NewThreadSafeClient(client QdrantClient, maxConnections int) *ThreadSafeClient {
	return &ThreadSafeClient{
		client:         client,
		maxConnections: maxConnections,
		connSemaphore:  make(chan struct{}, maxConnections),
		maxRetries:     3,
		retryBackoff:   100 * time.Millisecond,
	}
}

// acquireConnection 获取连接
func (tsc *ThreadSafeClient) acquireConnection(ctx context.Context) error {
	select {
	case tsc.connSemaphore <- struct{}{}:
		tsc.mutex.Lock()
		tsc.activeConns++
		tsc.mutex.Unlock()
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}

// releaseConnection 释放连接
func (tsc *ThreadSafeClient) releaseConnection() {
	tsc.mutex.Lock()
	tsc.activeConns--
	tsc.mutex.Unlock()
	<-tsc.connSemaphore
}

// withRetry 执行带重试的操作
func (tsc *ThreadSafeClient) withRetry(ctx context.Context, operation func() error) error {
	var lastErr error

	for attempt := 0; attempt <= tsc.maxRetries; attempt++ {
		if attempt > 0 {
			// 指数退避
			backoff := time.Duration(attempt) * tsc.retryBackoff
			select {
			case <-time.After(backoff):
			case <-ctx.Done():
				return ctx.Err()
			}
		}

		if err := operation(); err != nil {
			lastErr = err
			continue
		}

		return nil
	}

	return lastErr
}

// Initialize 线程安全的初始化
func (tsc *ThreadSafeClient) Initialize(config *Config) error {
	tsc.mutex.Lock()
	defer tsc.mutex.Unlock()

	return tsc.client.Initialize(config)
}

// Close 线程安全的关闭
func (tsc *ThreadSafeClient) Close() error {
	tsc.mutex.Lock()
	defer tsc.mutex.Unlock()

	return tsc.client.Close()
}

// HealthCheck 线程安全的健康检查
func (tsc *ThreadSafeClient) HealthCheck() error {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return err
	}
	defer tsc.releaseConnection()

	return tsc.withRetry(ctx, func() error {
		return tsc.client.HealthCheck()
	})
}

// InsertVectors 线程安全的向量插入
func (tsc *ThreadSafeClient) InsertVectors(vectors []Vector) error {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return err
	}
	defer tsc.releaseConnection()

	return tsc.withRetry(ctx, func() error {
		return tsc.client.InsertVectors(vectors)
	})
}

// SearchVectors 线程安全的向量搜索
func (tsc *ThreadSafeClient) SearchVectors(query Vector, limit int) ([]SearchResult, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return nil, err
	}
	defer tsc.releaseConnection()

	var results []SearchResult
	err := tsc.withRetry(ctx, func() error {
		var err error
		results, err = tsc.client.SearchVectors(query, limit)
		return err
	})

	return results, err
}

// DeleteVectors 线程安全的向量删除
func (tsc *ThreadSafeClient) DeleteVectors(ids []string) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return err
	}
	defer tsc.releaseConnection()

	return tsc.withRetry(ctx, func() error {
		return tsc.client.DeleteVectors(ids)
	})
}

// CreateCollection 线程安全的集合创建
func (tsc *ThreadSafeClient) CreateCollection(name string, config CollectionConfig) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return err
	}
	defer tsc.releaseConnection()

	return tsc.withRetry(ctx, func() error {
		return tsc.client.CreateCollection(name, config)
	})
}

// DeleteCollection 线程安全的集合删除
func (tsc *ThreadSafeClient) DeleteCollection(name string) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return err
	}
	defer tsc.releaseConnection()

	return tsc.withRetry(ctx, func() error {
		return tsc.client.DeleteCollection(name)
	})
}

// GetCollectionInfo 线程安全的集合信息获取
func (tsc *ThreadSafeClient) GetCollectionInfo(name string) (*CollectionInfo, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := tsc.acquireConnection(ctx); err != nil {
		return nil, err
	}
	defer tsc.releaseConnection()

	var info *CollectionInfo
	err := tsc.withRetry(ctx, func() error {
		var err error
		info, err = tsc.client.GetCollectionInfo(name)
		return err
	})

	return info, err
}

// GetStats 获取客户端统计信息
func (tsc *ThreadSafeClient) GetStats() map[string]interface{} {
	tsc.mutex.RLock()
	defer tsc.mutex.RUnlock()

	return map[string]interface{}{
		"max_connections":    tsc.maxConnections,
		"active_connections": tsc.activeConns,
		"max_retries":        tsc.maxRetries,
		"retry_backoff_ms":   tsc.retryBackoff.Milliseconds(),
	}
}

// SetRetryConfig 设置重试配置
func (tsc *ThreadSafeClient) SetRetryConfig(maxRetries int, backoff time.Duration) {
	tsc.mutex.Lock()
	defer tsc.mutex.Unlock()

	tsc.maxRetries = maxRetries
	tsc.retryBackoff = backoff
}
